﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.IO
{
    using System;
    using System.IO;

    /// <summary>Overrides <see cref="Stream"/> members associated with seeking so that they throw
    /// <see cref="NotSupportedException"/>.</summary>
    /// <threadsafety static="true" instance="false"/>
    public abstract class NonSeekableStream : Stream
    {
        /// <summary>See <see cref="Stream.CanSeek"/>.</summary>
        /// <value>Always <c>false</c>, even if the underlying stream supports seeking.</value>
        public sealed override bool CanSeek
        {
            get { return false; }
        }

        /// <summary>See <see cref="Stream.Length"/>.</summary>
        /// <exception cref="NotSupportedException">Thrown with each call.</exception>
        public sealed override long Length
        {
            get { throw CreateNotSupportedException(); }
        }

        /// <summary>See <see cref="Stream.SetLength"/>.</summary>
        /// <exception cref="NotSupportedException">Thrown with each call.</exception>
        public sealed override void SetLength(long value)
        {
            throw CreateNotSupportedException();
        }

        /// <summary>See <see cref="Stream.Position"/>.</summary>
        /// <exception cref="NotSupportedException">Thrown with each get or set operation.</exception>
        public sealed override long Position
        {
            get { throw CreateNotSupportedException(); }
            set { throw CreateNotSupportedException(); }
        }

        /// <summary>See <see cref="Stream.Seek"/>..</summary>
        /// <exception cref="NotSupportedException">Thrown with each call.</exception>
        public sealed override long Seek(long offset, SeekOrigin origin)
        {
            throw CreateNotSupportedException();
        }

        /// <summary>Gets whether <see cref="Stream.Dispose()"/> or <see cref="Stream.Close"/> has been called.
        /// </summary>
        protected abstract bool IsDisposed
        {
            get;
        }

        /// <summary>Checks whether the object has been disposed and if so throws <see cref="ObjectDisposedException"/>.
        /// </summary>
        protected void AssertNotDisposed()
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }

        /// <summary>Creates the exception thrown by all unsupported members.</summary>
        protected static Exception CreateNotSupportedException()
        {
            return new NotSupportedException("This operation is not supported.");
        }
    }
}
